﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Fractal : MonoBehaviour
{
    public Mesh[] meshes;
    public Material material;
    public int maxDepth;
    public float childScale;
    public float spawnProbability;//传递随机值判断是否跳过产生子节点

    public float maxRotationSpeed;//旋转
    public float maxTwist;//扭曲
    float rotationSpeed;
    int depth;
    Material[,] materials;


    private void InitializeMaterials()
    {
        materials = new Material[maxDepth + 1, 2];
        for (int i = 0; i <= maxDepth; i++)
        {
            float t = i / (maxDepth - 1f);
            t *= t;
            materials[i, 0] = new Material(material);
            materials[i, 0].color = Color.Lerp(Color.white, Color.yellow, t);
            materials[i, 1] = new Material(material);
            materials[i, 1].color = Color.Lerp(Color.white, Color.cyan, t);
        }
        materials[maxDepth, 0].color = Color.magenta;
        materials[maxDepth, 1].color = Color.red;
    }
    void Start()
    {
        rotationSpeed = Random.Range(-maxRotationSpeed, maxRotationSpeed);
        transform.Rotate(Random.Range(-maxTwist, maxTwist), 0f, 0f);
        if (materials == null)
        {
            InitializeMaterials();
        }
        gameObject.AddComponent<MeshFilter>().mesh = meshes[Random.Range(0, meshes.Length)]; //添加filter
        gameObject.AddComponent<MeshRenderer>().material = materials[depth, Random.Range(0, 2)];//添加material
        if (depth < maxDepth)
        {
            //协程
            StartCoroutine(CreateChildren());

        }


    }

    private static Vector3[] childDirecions = {
        Vector3.up,
        Vector3.right,
        Vector3.left,
        Vector3.forward,
        Vector3.back
    };

    private static Quaternion[] childOrientation ={
        Quaternion.identity,
        Quaternion.Euler(0f,0f,-90f),
        Quaternion.Euler(0f,0f,90f),
        Quaternion.Euler(90f,0f,0f),
        Quaternion.Euler(-90f,0f,0f)
    };
    //初始化对象
    private void Initialize(Fractal parent, int childIndex)
    {
        meshes = parent.meshes;
        materials = parent.materials;
        spawnProbability = parent.spawnProbability;
        maxRotationSpeed = parent.maxRotationSpeed;
        maxTwist = parent.maxTwist;
        maxDepth = parent.maxDepth;
        depth = parent.depth + 1;
        childScale = parent.childScale;
        transform.parent = parent.transform;//父子层级
        transform.localScale = Vector3.one * childScale;//缩放
        transform.localPosition = childDirecions[childIndex] * (0.5f + 0.5f * childScale);//根据direction进行位移
        transform.localRotation = childOrientation[childIndex];//旋转定向
    }
    //IEnumerator 枚举器
    private IEnumerator CreateChildren()
    {
        for (int i = 0; i < childDirecions.Length; i++)
        {
            if (Random.value < spawnProbability)
            {

                //yield语句被迭代器用来控制协程的生命周期
                yield return new WaitForSeconds(Random.Range(0.1f, 0.5f));//等待0.5秒
                new GameObject("Fractal Child").AddComponent<Fractal>().Initialize(this, i);
            }
        }


    }
    void Update()
    {
        transform.Rotate(0f, rotationSpeed * Time.deltaTime, 0f);
    }
}
